package io.hilo.example.demo.service;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import org.apache.commons.io.FileUtils;
import org.hilo.boot.core.UT;
import org.jretty.util.Const;
import org.jretty.util.IOUtils;
import org.jretty.util.NestedIOException;
import org.jretty.util.NestedRuntimeException;
import org.jretty.util.StringUtils;
import org.jretty.util.zip.ZipException;
import org.jretty.util.zip.ZipUtils;
import org.jretty.util.FileUtils.TextFileParse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;


/**
 * Service Demo
 * 业务逻辑处理
 * 
 * @author xxxx
 * @since 2023-10-12
 */
@Service
public class GeneratorService {
    private static Logger LOGGER = LoggerFactory.getLogger(GeneratorService.class);
    
    public byte[] generatorCode(String useType, String groupId, String artifactId, String basePackage) {
        return test(useType, groupId, artifactId, basePackage);
    }
    
    public static void main0(String[] args) throws IOException {
        byte[] aa = test("web", "com.company", "demo-web", "com.company.project");
        if (aa != null) {
            System.out.println("00000000000=" + aa.length);
        }
    }
    
    public static byte[] test(String useType, String groupId, String artifactId, String basePackage) {
        String batPath = "D:\\C\\devsoft\\apache-maven-3.5.0\\bin\\mvn.cmd archetype:generate -B -DarchetypeGroupId=com.zollty -DarchetypeArtifactId={}-archetype -DarchetypeVersion=1.0.0-SNAPSHOT -DgroupId={} -DartifactId={} -Dversion=1.0-SNAPSHOT -Dpackage={}"; // 把你的bat脚本路径写在这里
//        File batFile = new File(batPath);
//        boolean batFileExist = batFile.exists();
//        System.out.println("batFileExist:" + batFileExist);
//        if (batFileExist) {
//            callCmd(batPath);
//        }
        if(useType.equals("admin")) {
            useType = "hilo-demo-admin";
        } else if(useType.equals("web")) {
            useType = "hilo-demo-web";
        } else if(useType.equals("dubbo")) {
            useType = "hilo-demo-dubbo";
        } else {
            return null;
        }
        if(basePackage==null) {
            basePackage = groupId;
        }
        batPath = UT.Str.replaceParams(batPath, useType, groupId, artifactId, basePackage);
        String rpath = UT.Random.getRadomStr09az(10);
        File path = createTempDir(rpath);
        path.deleteOnExit();
        System.out.println("------------------path=" + path);
        boolean ret = callCmd(batPath, path);
        if(!ret) {
            return null;
        }
      
        String tempath = path.getAbsolutePath() + "/" + artifactId;
        try {
            ZipUtils.zipFile(tempath + ".zip", tempath);
        } catch (ZipException e) {
            e.printStackTrace();
        }
        
        UT.File.deleteAll(new File(tempath));
        
        System.out.println("----------------------------------------done!");
        byte[] bret=null;
        try {
            bret = FileUtils.readFileToByteArray(new File(tempath + ".zip"));
        } catch (IOException e) {
            e.printStackTrace();
        }
        new File(tempath + ".zip").delete();
        UT.File.deleteAll(path);
        return bret;
    }
    
//    public static File createTempDir(String name) throws IOException {
//        File tempDir = File.createTempFile(name, null);
//        tempDir.delete();
//        tempDir.mkdir();
//        tempDir.deleteOnExit();
//        return tempDir;
//    }
    
    public static File createTempDir(String folderName) {
        File tmpdir = new File(System.getProperty("java.io.tmpdir"));
        tmpdir = new File(tmpdir, folderName);
        if (!tmpdir.exists()) {
            tmpdir.mkdir();
        }
        return tmpdir;
    }
    
    private static boolean callCmd(String locationCmd, File dir){
        StringBuilder sb = new StringBuilder();
        try {
            Process child = Runtime.getRuntime().exec(locationCmd, null, dir);
            InputStream in = child.getInputStream();
            BufferedReader bufferedReader=new BufferedReader(new InputStreamReader(in));
            String line;
            while((line=bufferedReader.readLine())!=null)
            {
                //sb.append(line + "\n");
                System.out.println(line);
            }
            in.close();
            try {
                child.waitFor();
            } catch (InterruptedException e) {
                System.out.println(e);
            }
            System.out.println("sb:" + sb.toString());
            System.out.println("callCmd execute finished");   
            return true;
        } catch (IOException e) {
            e.printStackTrace();
            return false;
        }
     }
    
    public static void main1(String[] args) {
        test();
    }
    
    public static final String OLD_PATH = "org.hilo.boot";
    public static final String NEW_PATH = "org/hilo/framework";
    public static final String OLD_PACK = "org.hilo.boot";
    public static final String NEW_PACK = "org.hilo.boot";
    public static void test() {
        TextFileParse<String> parser = new TextFileParse<String>() {
            @Override
            public String parseOneLine(String line) {
                return line.replaceAll(OLD_PACK, NEW_PACK).replaceAll("hilo", "hilo");
            }
        };
        
        String sourceDir = UT.Path.normalPath("D:\\test1\\source");
        String targetDir = UT.Path.normalPath("D:\\test1\\target");
        List<File> files = UT.File.loopFiles(new File(sourceDir), null); 
        for (File file : files) {
            String fileFullPath = UT.Path.normalPath(file.getAbsolutePath());
            String targetPath = fileFullPath.replace(sourceDir, targetDir);
            targetPath = targetPath.replace(OLD_PATH, NEW_PATH);
            targetPath = targetPath.replace("hilo", "hilo");
//            if(file.isDirectory()) {
//                new File(targetPath).mkdirs();
//                continue;
//            }
            parseTextFile(fileFullPath, parser, targetPath);
        }
    }
    
    /**
     * 按行解析文本文件
     */
    public static void parseTextFile(String fileFullPath, TextFileParse<String> parser, String targetPath) {
        InputStream in;
        try {
            in = new FileInputStream(fileFullPath);
        }
        catch (FileNotFoundException e) {
            throw new NestedRuntimeException(e);
        }
        
        BufferedWriter out = null;
        try {
            File file1 = new File(targetPath);
            File fileParent = file1.getParentFile();
            if (!fileParent.exists()) {
                fileParent.mkdirs();
            }
            file1.createNewFile();
            
            out = UT.File.getBufferedWriter(targetPath, false, Const.DEFAULT_CHARSET);
        }
        catch (IOException e) {
            IOUtils.closeIO(in);
            throw new NestedRuntimeException(e);
        }
        
        BufferedReader br = null;
        try {
            br = new BufferedReader(new InputStreamReader(in, Const.DEFAULT_CHARSET));
            String o;
            String lineStr;
            while ((lineStr = br.readLine()) != null) {
                if (StringUtils.isNotEmpty(lineStr)) {
                    // 读出文件中一行的数据
                    o = parser.parseOneLine(lineStr);
                    if (o != null) {
                        out.append(o).append("\r\n");
                    }
                } else {
                    out.append(lineStr).append("\r\n");
                }
            }
        }
        catch (Exception e) {
            throw new NestedRuntimeException(e);
        }
        finally {
            IOUtils.closeIO(out);
            IOUtils.closeIO(in);
        }
    }

}
